<?php

/**
 * \file
 * Classe `field`.
 */

/**
 * Champs de données des membres abstraits.
 */
namespace pilar\Entities\Fields /* \cond */ ; /* \endcond */
{

/**
 * Champ de donnée d'un membre abstrait.
 *
 * \since 27/07/2008
 * \author Matthieu OVIEDO <matthieu.oviedo@gmail.com>
 */
abstract class Field extends \object {

/**
 * Membre parent.
 */
public $parentMember;


/**
 * \todo
 * Matthieu : Revoir le nom et l'interêt du paramètre 'sqlExpression'.
 */
protected function loadDefaultParams() {
 parent::loadDefaultParams();

 $this->params->define(array(
  'name' => 'value', // Nom du champ.
  'defaultValue' => '',
  'protected' => false,
  'sqlExpression' => 'eq' // Expression sql à utiliser pour une recherche.
 ));
}


/**
 * Permet de spécifier le membre parent du champ.
 *
 * \param $member Membre parent.
 */
public function setParentMember($member) {
 $this->parentMember = $member;
}


/**
 * Nom complet du champ en base de données.
 * 
 * \return Nom complet du champ.
 */
public function fullName() {
 return (
  $this->parentMember->get('name') .
  \capitalize($this->get('name'))
 );
}


/**
 * Génère un code d'assignation SQL.
 * 
 * \param $value Valeur souhaitée pour le champ.
 * \return Code SQL d'assignation.
 */
public function sqlAssignationCode($value) {
 return "`".$this->fullName()."` = '".\db\escape($value)."'";
}


/**
 * Génère le code SQL de définition du champ.*
 * 
 * \since 09/09/2008
 * \return Code de définition du champ sur une ligne.
 */
abstract public function sqlProperties();

 
/**
 * Détermine si la colonne du champ existe en base de données. La fonction
 * suppose que la table existe.
 * 
 * \since 01/10/2008
 * \return TRUE si la colonne existe, sinon FALSE.
 */
public function columnExists() {
 $result = \db\query(
    'SHOW COLUMNS FROM '
  . '`'.$this->parentMember->parentEntity->sqlTableName().'` '
  . 'LIKE \''.$this->fullName().'\''
 );
 
 return !$result->isEmpty();
}


/**
 * Crée la colonne associée au champ en supposant que celle-ci n'existe pas
 * en base de données. La fonction suppose que la table existe.
 * 
 * \since 01/10/2008
 */
public function createColumn() {
 \db\execute(
    'ALTER TABLE '
  . '`'.$this->parentMember->parentEntity->sqlTableName().'` '
  . 'ADD COLUMN `'.$this->fullName().'` '
  . $this->sqlProperties()
 );
}


/**
 * Met à jour la définition de la colonne en base de données en supposant que
 * la table existe.
 * 
 * \since 01/10/2008
 */
public function updateColumn() {
 \db\execute(
    'ALTER TABLE '
  . '`'.$this->parentMember->parentEntity->sqlTableName().'` '
  . 'CHANGE COLUMN `'.$this->fullName().'` '
  . '`'.$this->fullName().'` '.$this->sqlProperties()
 );
}


/**
 * S'assure que la colonne en base de données associée au champ soit bien à
 * niveau. La fonction suppose que la table existe.
 * 
 * \since 01/10/2008
 */
public function upgradeColumn() {
 if($this->columnExists()) {
  $this->updateColumn();
 } else {
  $this->createColumn();
 }
}


/**
 * Détermine si le champ est protégé en écriture de manière générale.
 *
 * \since 07/10/2008
 * \return TRUE / FALSE.
 */
public function isProtected() {
 return $this->get('protected') || $this->parentMember->isProtected();
}


/**
 * Détermine si une valeur est syntaxiquement acceptable pour le champ.
 *
 * \since 07/10/2008
 * \return TRUE / FALSE.
 */
public function acceptsValue($value) {
 return $this->parentMember->acceptsFieldValue(
  $this->get('name'),
  $value
 );
}


/**
 * Formate une valeur potentielle du champ.
 *
 * \since 07/10/2008
 * \return Valeur formatée.
 */
public function formatValue($value) {
 return $this->parentMember->formatFieldValue(
  $this->get('name'),
  $value
 );
}


/**
 * Calcule la valeur par défaut qu'un champ d'objet aurait à l'instant
 * présent.
 *
 * \return Valeur par défaut.
 *
 * \since 05/02/2009
 */
public function computeDefaultValue() {
 return $this->get('defaultValue');
}


} // Class.

} // Namespace.

?>
